package com.yonyou.dao;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.mongodb.gridfs.GridFsTemplate;
import org.springframework.stereotype.Component;

import com.yonyou.domain.Department;
import com.yonyou.domain.DrawTurn;
import com.yonyou.domain.PresetWinning;
import com.yonyou.domain.Prize;
import com.yonyou.domain.User;
import com.yonyou.domain.UserId;
import com.yonyou.domain.Winners;
import com.yonyou.domain.WinningList;
import com.yonyou.exception.BusinessException;
import com.yonyou.service.extend.UserServiceInterfaceClient;
import com.yonyou.status.CommnonStatus;

@Component
public class WinningListDAO {

	@Autowired
	public MongoTemplate mongoTemplate;

	@Autowired
	public GridFsTemplate gridFsTemplate;

	@Autowired
	public UserServiceInterfaceClient userServiceInterfaceClient;
	
	public List<WinningList> saveWinners(Winners winners) throws BusinessException {
		if (winners.getMeeting_id()== null || "".equals(winners.getMeeting_id())) {
			throw new BusinessException("会议为空,无法保存中奖信息!");
		}
		if (winners.getPrize_id()== null || "".equals(winners.getPrize_id())) {
			throw new BusinessException("奖项为空,无法保存中奖信息!");
		}
		List<WinningList> list = new ArrayList<>();
		// 查询奖项信息
		Criteria criteria_prize = Criteria.where("id").is(winners.getPrize_id());
		Query query_prize = Query.query(criteria_prize);
		Prize prize = mongoTemplate.findOne(query_prize, Prize.class);
		if (prize== null) {
			throw new BusinessException("奖项为空,无法保存中奖信息!");
		}
		List<String> userIds = winners.getUser_ids();
		for (Iterator<String> iterator = userIds.iterator(); iterator.hasNext();) {
			String user_id = (String) iterator.next();
			User user = userServiceInterfaceClient.findUserById(user_id).getData();
			WinningList winningList = new WinningList();
			winningList.setMeeting_id(winners.getMeeting_id());
			winningList.setPrize_id(prize.getId());
			winningList.setUser_id(user_id);
			winningList.setDr(CommnonStatus.SAVSTATUS);
			winningList.setDraw_form(CommnonStatus.DRAWFORMBYMAN);
			winningList.setUser(user);
			winningList.setPrize(prize);
			mongoTemplate.insert(winningList);// 保存中奖名单
			list.add(winningList);
		}
		return list;
	}
	/**
	 * 查询用户是否中奖
	 * @throws BusinessException 
	 */
	public List<WinningList> whetherWinning(String meeting_id, String user_id) throws BusinessException {
		if (meeting_id== null || "".equals(meeting_id)) {
			throw new BusinessException("会议为空,无法获取中奖信息!");
		}
		if (user_id== null || "".equals(user_id)) {
			throw new BusinessException("用户为空,无法获取中奖信息!");
		}
		// 查询中奖名单列表
		Criteria criteria = Criteria.where("dr").is(CommnonStatus.SAVSTATUS);
		criteria.andOperator(Criteria.where("user_id").is(user_id),Criteria.where("meeting_id").is(meeting_id));
		Query query = Query.query(criteria);
		// 放入奖项和中奖用户信息
		List<WinningList> winningListList = mongoTemplate.find(query, WinningList.class);
		return winningListList;
	}
	/***
	 * 查询中奖名单
	 * 
	 * @param meeting_id
	 * @param prize_id
	 * @return
	 */
	public List<WinningList> getWinningList(String meeting_id, String prize_id) {
		// 查询中奖名单列表
		Criteria criteria = Criteria.where("dr").is(CommnonStatus.SAVSTATUS);
		if (prize_id != null && !"".equals(prize_id)&&meeting_id != null && !"".equals(meeting_id)) {
			criteria.andOperator(Criteria.where("prize_id").is(prize_id),Criteria.where("meeting_id").is(meeting_id));
		}
		else if (meeting_id != null && !"".equals(meeting_id)) {
			criteria.andOperator(Criteria.where("meeting_id").is(meeting_id));
		}else if (prize_id != null && !"".equals(prize_id)) {
			criteria.andOperator(Criteria.where("prize_id").is(prize_id));
		}
		Query query = Query.query(criteria);
		// 放入奖项和中奖用户信息
		List<WinningList> winningListList = mongoTemplate.find(query, WinningList.class);
		return winningListList;
	}
	
	

	/**
	 * 设为未领奖或已领奖
	 * 
	 * @param id
	 * @param is_accept
	 */
	public void updateWinningList(String id, String is_accept) {
		Query query = Query.query(Criteria.where("id").is(id));
		Update update = Update.update("is_accept", is_accept);
		mongoTemplate.updateFirst(query, update, WinningList.class);
	}

	/**
	 * 删除全部中奖名单
	 * 
	 * @param meeting_id
	 * @param prize_id
	 */
	public void deleteWinningList(String meeting_id, String prize_id) {
		Criteria criteria = Criteria.where("dr").is(CommnonStatus.SAVSTATUS);
		if (prize_id != null && !"".equals(prize_id)&&meeting_id != null && !"".equals(meeting_id)) {
			criteria.andOperator(Criteria.where("prize_id").is(prize_id),Criteria.where("meeting_id").is(meeting_id));
		}
		else if (meeting_id != null && !"".equals(meeting_id)) {
			criteria.andOperator(Criteria.where("meeting_id").is(meeting_id));
		}else if (prize_id != null && !"".equals(prize_id)) {
			criteria.andOperator(Criteria.where("prize_id").is(prize_id));
		}
		Query query = Query.query(criteria);
		Update update = Update.update("dr", CommnonStatus.DELSTATUS);
		mongoTemplate.updateMulti(query, update, WinningList.class);
		updatePrize(prize_id, 0);//清零奖项抽奖轮次
		updateMeetingPrize(meeting_id, 0);//清零会议下所有奖项的抽奖轮次
	}

	/**
	 * 获取本轮抽奖奖项的轮次信息
	 * 
	 * @param list
	 * @return
	 */
	public DrawTurn getDrawTurn(List<DrawTurn> list, Integer turn) {
		DrawTurn drawTurn = null;
		for (Iterator<DrawTurn> iterator = list.iterator(); iterator.hasNext();) {
			DrawTurn drawTurnTemp = (DrawTurn) iterator.next();
			if ((turn + 1) == drawTurn.getTurn()) {
				drawTurn = drawTurnTemp;
			}
		}
		return drawTurn;

	}

	/**
	 * 根据奖项抽奖
	 * 
	 * @return
	 * @throws BusinessException
	 */
	public List<WinningList> drawPirze(String prize_id) throws BusinessException {
		if (prize_id == null || "".equals(prize_id)) {
			throw new BusinessException("奖项ID为空,无法获取奖项信息!");
		}
		List<WinningList> list = new ArrayList<>();
		// 查询奖项信息
		Criteria criteria_prize = Criteria.where("prize_id").is(prize_id);
		Query query_prize = Query.query(criteria_prize);
		Prize prize = mongoTemplate.findOne(query_prize, Prize.class);
		// 查询会议下的中奖记录信息
		Criteria criteria_winningList = Criteria.where("dr").is(CommnonStatus.SAVSTATUS);
		criteria_winningList.andOperator(Criteria.where("meeting_id").is(prize.getMeeting_id()));
		Query query_winningList = Query.query(criteria_winningList);
		List<WinningList> winningList = mongoTemplate.find(query_winningList, WinningList.class);
		List<DrawTurn> drawTurnList = prize.getList();
		Integer turn = prize.getTurn();
		// 判断奖项下中奖名额是否抽完,判断抽奖轮次是否已用完
		if (prize.getTurn() >= drawTurnList.size()) {
			throw new BusinessException("本奖项已抽完");
		}
		DrawTurn drawTurn = getDrawTurn(drawTurnList, turn);// 抽奖轮次
		String draw_form = drawTurn.getDraw_form();// 抽奖形式
		if (CommnonStatus.DRAWFORMBYMAN.equals(draw_form)) {
			List<UserId> user = userServiceInterfaceClient.findUserByMeeting(prize.getMeeting_id()).getData();// 远程调用接口获取抽奖人员
			List<String> userIds = new ArrayList<String>();
			for (Iterator<UserId> iterator = user.iterator(); iterator.hasNext();) {
				UserId userId = (UserId) iterator.next();
				userIds.add(userId.getId());
			}
			List<String> winningUserids = getDrawManList(winningList);// 获取会议下的已中奖人员ID集合
			userIds = getLastManList(userIds, winningUserids);// 去除已经抽中奖的人员
			list = drawByUser(userIds, prize, drawTurn, winningUserids);
		}
		if (CommnonStatus.DRAWFORMBYDEPT.equals(draw_form)) {
			List<Department> depts = userServiceInterfaceClient.findDeptByMeeting(prize.getMeeting_id()).getData();// 远程调用接口获取参会抽奖部门集合
			List<String> deptIds = new ArrayList<String>();
			for (Iterator<Department> iterator = depts.iterator(); iterator.hasNext();) {
				Department department = (Department) iterator.next();
				deptIds.add(department.getId());
			}
			List<String> winningDeptids = getDrawDeptList(winningList);// 获取中奖部门ID的集合
			deptIds = getLastDeptList(deptIds, winningDeptids);// 去除已经中奖部门后的集合
			list = drawByDept(deptIds, drawTurn, prize);
		}
		return list;
	}

	/**
	 * 获取中奖部门ID的集合
	 * 
	 * @return
	 */
	private List<String> getDrawDeptList(List<WinningList> winningList) {
		List<String> deptIdList = new ArrayList<>();
		for (Iterator<WinningList> iterator = winningList.iterator(); iterator.hasNext();) {
			WinningList winningList2 = (WinningList) iterator.next();
			if (CommnonStatus.DRAWFORMBYDEPT.equals(winningList2.getDraw_form())) {
				deptIdList.add(winningList2.getUser().getDepartment().getId());
			}
		}
		return deptIdList;
	}

	/***
	 * 去除已经中奖部门后的集合
	 */
	private List<String> getLastDeptList(List<String> deptIds, List<String> winningDeptids) {
		List<String> drawList = new ArrayList<>();
		for (Iterator<String> iterator = winningDeptids.iterator(); iterator.hasNext();) {
			String string = (String) iterator.next();
			if (!winningDeptids.contains(string)) {
				drawList.add(string);
			}
		}
		return drawList;
	}

	/**
	 * 获取中奖人员ID的集合
	 * 
	 * @return
	 */
	private List<String> getDrawManList(List<WinningList> winningList) {
		List<String> userIdList = new ArrayList<>();
		for (Iterator<WinningList> iterator = winningList.iterator(); iterator.hasNext();) {
			WinningList winningList2 = (WinningList) iterator.next();
			if (CommnonStatus.DRAWFORMBYMAN.equals(winningList2.getDraw_form())) {
				userIdList.add(winningList2.getUser().getId());
			}
		}
		return userIdList;
	}

	/***
	 * 去除已经中奖人员ID的集合
	 */
	private List<String> getLastManList(List<String> userIds, List<String> winningUserids) {
		List<String> drawList = new ArrayList<>();
		for (Iterator<String> iterator = winningUserids.iterator(); iterator.hasNext();) {
			String string = (String) iterator.next();
			if (!winningUserids.contains(string)) {
				drawList.add(string);
			}
		}
		return drawList;
	}

	/**
	 * 获取内定中奖人员（去除已经中奖的内定中奖人员）
	 */
	public List<PresetWinning> getPresetWinningList(Prize prize, List<String> winningUserids) {
		Criteria criteria = Criteria.where("meeting_id").is(prize.getMeeting_id());
		criteria.andOperator(Criteria.where("dr").is(CommnonStatus.SAVSTATUS));
		Query query = Query.query(criteria);
		List<PresetWinning> list = mongoTemplate.find(query, PresetWinning.class);
		List<PresetWinning> returnList = new ArrayList<>();
		for (Iterator<PresetWinning> iterator = list.iterator(); iterator.hasNext();) {
			PresetWinning presetWinning = (PresetWinning) iterator.next();
			if (!winningUserids.contains(presetWinning.getUser_id())) {
				returnList.add(presetWinning);
			}
		}
		return returnList;
	}

	/**
	 * 按人抽
	 */
	private List<WinningList> drawByUser(List<String> user, Prize prize, DrawTurn drawTurn,
			List<String> winningUserids) {
		Integer winning_quota = drawTurn.getWinning_quota();// 一次抽取中奖名额
		Random random = new Random();
		Set<String> set = new HashSet<String>();
		// 内定抽奖
		List<PresetWinning> presetWinningList = getPresetWinningList(prize, winningUserids);
		// 内定抽奖人员>=中奖名额，只从内定人员里抽取
		if (presetWinningList.size() >= winning_quota) {
			while (set.size() != winning_quota) {
				set.add(presetWinningList.get(random.nextInt(user.size())).getId());
			}
		}
		// 内定抽奖人员<中奖名额，内定中奖人员默认为全部中奖，然后从其它人员里抽取剩余的
		else {
			for (Iterator<PresetWinning> iterator = presetWinningList.iterator(); iterator.hasNext();) {
				PresetWinning presetWinning = (PresetWinning) iterator.next();
				set.add(presetWinning.getId());
			}
			if (user != null && !user.isEmpty()) {
				while (set.size() != winning_quota) {
					set.add(user.get(random.nextInt(user.size())));
				}
			}
		}
		return insertUserWinningList(set, prize);
	}

	/**
	 * 按部门抽
	 */
	private List<WinningList> drawByDept(List<String> dept, DrawTurn drawTurn, Prize prize) {
		List<User> users = new ArrayList<>();
		Random random = new Random();
		Set<String> set = new HashSet<String>();
		if (dept != null && !dept.isEmpty()) {
			while (set.size() != drawTurn.getWinning_quota()) {
				set.add(dept.get(random.nextInt(dept.size())));
			}
		}
		for (Iterator<String> iterator = set.iterator(); iterator.hasNext();) {
			String string = (String) iterator.next();
			users.addAll(userServiceInterfaceClient.findUserByDept(prize.getMeeting_id(), string).getData());
		}
		return insertDeptWinningList(users, prize);
	}

	/**
	 * 保存中奖人员名单
	 * 
	 * @param user
	 */
	private List<WinningList> insertUserWinningList(Set<String> userIds, Prize prize) {
		List<WinningList> list = new ArrayList<>();
		for (Iterator<String> iterator = userIds.iterator(); iterator.hasNext();) {
			String user_id = (String) iterator.next();
			User user = userServiceInterfaceClient.findUserById(user_id).getData();
			WinningList winningList = new WinningList();
			winningList.setPrize_id(prize.getId());
			winningList.setDr(CommnonStatus.SAVSTATUS);
			winningList.setDraw_form(CommnonStatus.DRAWFORMBYMAN);
			winningList.setUser(user);
			winningList.setPrize(prize);
			mongoTemplate.insert(winningList);// 保存中奖名单
		}
		updatePrize(prize.getId(),prize.getTurn()+1);
		return list;
	}

	/**
	 * 保存按部门抽的中奖人员名单
	 */
	private List<WinningList> insertDeptWinningList(List<User> users, Prize prize) {
		List<WinningList> list = new ArrayList<>();
		for (Iterator<User> iterator = users.iterator(); iterator.hasNext();) {
			User user = (User) iterator.next();
			WinningList winningList = new WinningList();
			winningList.setPrize_id(prize.getId());
			winningList.setDraw_form(CommnonStatus.DRAWFORMBYDEPT);
			winningList.setDr(CommnonStatus.SAVSTATUS);
			winningList.setUser(user);
			winningList.setPrize(prize);
			mongoTemplate.insert(winningList);// 保存中奖名单
		}
		updatePrize(prize.getId(),prize.getTurn()+1);
		return list;
	}
	
	/**
	 * 更新奖项的轮次
	 * @param prize
	 */
	private void updatePrize(String prize_id,Integer turn){
		Query query = Query.query(Criteria.where("id").is(prize_id));
		Update update = Update.update("turn", turn);
		mongoTemplate.updateFirst(query, update, Prize.class);
	}
	/**
	 * 更新会议下所有奖项的轮次
	 * @param prize
	 */
	private void updateMeetingPrize(String prize_id,Integer turn){
		Query query = Query.query(Criteria.where("id").is(prize_id));
		Update update = Update.update("turn", turn);
		mongoTemplate.updateMulti(query, update, Prize.class);
	}

}
